﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using Thread = System.Threading.Tasks;
using Microsoft.Practices.Unity;
using Infrastucture;
using Infrastucture.Collections;
using TimeSplicerModule.Factories;
using TimeSplicerModule.DomainModels;
using TimeSplicerModule.Security;
using TimeSplicerModule.ViewModels;

namespace TimeSplicerModule.Services
{
    public partial class ProjectService : IProjectService
    {
        public ProjectListViewModel GetProjectListViewModel()
        {
            _session = _container.Resolve<ISession>();
            var model = new ProjectListViewModel();
            model.FilteredTasks = new List<TaskModel>();
            model.FilteredProjects = new ObservableCollection<ProjectModel>();
            model.SelectedUserGuid = _session.User.UserGuid;

            var priorities = _session.Priorities;
            //StatusModel[] sta = new StatusModel[_session.Statuses.Count];
            var temp = _session.Statuses.Where(x => x.IsProjectStatus && x.IsActive).ToList(); // Going to Alter this a bit
            StatusModel[] sta = new StatusModel[temp.Count];
            temp.CopyTo(sta);
            model.Statuses = _session.Statuses.Where(x => x.IsProjectStatus && x.IsActive).ToList().ConvertAll(x =>
            {
                x = ModelConverter.ToModel<StatusModel>(x);
                return x;
            });
            model.Users = _userService.GetViewableUsers(); 
            var allUsers = _userFactory.GetList();
            var projectRoles= _projectRoleFactory.GetList();
            var allProjectUsers = _projectUserFactory.GetList(allUsers, projectRoles);
            model.ProjectUsers = allProjectUsers;

            // Need to change this to only get projects for current user
            model.Projects = _projectFactory.GetList(_session.Statuses, priorities, allUsers);
            model.Projects.AsParallel().ForAll(x => { x.ProjectUsers = allProjectUsers.Where(a => a.ProjectGuid == x.ProjectGuid).ToList(); });

            
            // filter tp projcecs this user is associated with 
            var projectIds = allProjectUsers.Where(x => x.UserGuid == model.SelectedUserGuid).Select(x => x.ProjectGuid).Distinct().ToList();

            // active statuses
            var statuses = _session.Statuses;
            var notStarted = statuses.FirstOrDefault(x => x.Status == Status.Not_Started);
            var active = statuses.FirstOrDefault(x => x.Status == Status.Active);
            // add a not started/ active status together
            var combinded = new StatusModel
            {
                StatusGuid = Guid.Empty,
                Name = "Active/Not Started",
                SortOrder = -1
            };

            model.Statuses.Add(combinded);
            model.Statuses = model.Statuses.OrderBy(o => o.SortOrder).ToList();

            foreach (var p in projectIds)
            {
                var project = model.Projects.FirstOrDefault(x => x.ProjectGuid == p);

                if (project != null)
                {
                    project.ProjectUsers = allProjectUsers.Where(x => x.ProjectGuid == project.ProjectGuid).ToList();

                    if (project.StatusGuid == notStarted.StatusGuid || project.StatusGuid == active.StatusGuid)
                        model.FilteredProjects.Add(project);
                }
            }

            model.FilteredProjects = model.FilteredProjects.OrderBy(o => o.Status.SortOrder).ToObservableCollection();

            // enabled disable create new button
            model.IsEnabled = _session.User.ApplicationRole.Hierarchy <= 5; // need to adjust this


            var userProjects = model.Projects.Where(x => x.ProjectUsers.Exists(e => e.UserGuid == _session.User.UserGuid)).ToList();

            model.Statuses.ForEach(x =>
            {
                if (x.StatusGuid != Guid.Empty)
                {
                    x.Name += " (" + userProjects.Count(s => s.StatusGuid == x.StatusGuid) + ")";
                }
                else
                {
                    x.Name += " (" + userProjects.Count(s => s.Status.Status == Status.Active
                        || s.Status.Status == Status.Not_Started) + ")";
                }
            });


            return model;
        }
    }
}
